package weifei.live.simulation.im;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.Data;
import weifei.live.simulation.entity.ChatGroup;
import weifei.live.simulation.entity.GroupLiveStreamVideoTimeCache;
import weifei.live.simulation.entity.GroupMember;

import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;


/**
 * 直播间 与 群 绑定
 * */
@Data
public class GroupLiveStreamManager
{
    private QueryWrapper<ChatGroup> qw_group = new QueryWrapper<>();
    private QueryWrapper<GroupMember> qw_group_member = new QueryWrapper<>();
    private QueryWrapper<GroupLiveStreamVideoTimeCache> qw_live_stream_video_time_cache = new QueryWrapper<>();


    // LiveStreamManagerMap
    // groupId 与 manager 对应，查 群聊对应直播间
    private static final ConcurrentHashMap<Integer, GroupLiveStreamManager> groupIdLiveStreamManagerMap = new ConcurrentHashMap<>();  // liveStreamId, LiveStream
    // userId 与 manager 对应，查 用户所在直播间
    private static final ConcurrentHashMap<Integer, GroupLiveStreamManager> userIdLiveStreamManagerMap = new ConcurrentHashMap<>();


    private int groupId;            // 直播的群的ID
    private Integer[] streamIds;    // 主播ID
    private String name;            // 直播间 的 名字
    private CopyOnWriteArraySet<Integer> userIdSet = new CopyOnWriteArraySet<>();


    private GroupLiveStreamManager(int groupId, String name) {
        this.groupId = groupId;
        this.streamIds = this.getStreamerIds();
        this.name = name;
    }


    public String getVideoURL()
    {
        var now = new Date();
        this.qw_live_stream_video_time_cache.clear();
        this.qw_live_stream_video_time_cache.eq(GroupLiveStreamVideoTimeCache.Column.GroupID.getName(), this.groupId);
        this.qw_live_stream_video_time_cache.le(GroupLiveStreamVideoTimeCache.Column.StartTime.getName(), now);
        this.qw_live_stream_video_time_cache.ge(GroupLiveStreamVideoTimeCache.Column.EndTime.getName(), now);
        var cache = new GroupLiveStreamVideoTimeCache().selectOne(this.qw_live_stream_video_time_cache);
        return cache.getVideoURL();
    }


    public GroupLiveStream toGroupLiveStream()
    {
        return new GroupLiveStream(this.groupId, this.name, this.getVideoURL());
    }


    /**
     * 获取 群直播间 主播ID
     * */
    private Integer[] getStreamerIds()
    {
        var owner_id = new ChatGroup(this.groupId).selectById().getOwnerId();

        this.qw_group_member.clear();
        this.qw_group_member.eq(GroupMember.Column.GroupID.getName(), this.groupId);
        this.qw_group_member.eq(GroupMember.Column.Capacity.getName(), GroupMember.Capacity.Adminer);
        var gm = new GroupMember();
        var list_m = gm.selectList(this.qw_group_member);

        var result = new Integer[list_m.size() + 1];
        result[list_m.size()] = owner_id;
        for (int i = 0; i < list_m.size(); i++)         //这样效率高点
            result[i] = list_m.get(i).getUserId();
        return result;
    }
    public boolean isStreamer(int streamerId)
    {
        for (var i : this.streamIds)
        {
            if (i == streamerId)
                return true;
        }
        return false;
    }


    public void addUserId(int userId)
    {
        if (this.userIdSet.add(userId))
            GroupLiveStreamManager.userIdLiveStreamManagerMap.put(userId, this);    // userId 与 直播间 关联
    }
    public void removeUserId(int userId)
    {
        if (this.userIdSet.remove(userId))
            GroupLiveStreamManager.userIdLiveStreamManagerMap.remove(userId);    // userId 与 直播间 关联去除
    }
    public void removeUserIds()
    {
        var ids = this.getUserIds();
        for (var i : ids)
            this.removeUserId(i);
    }
    public Integer[] getUserIds() {
        return this.userIdSet.toArray(new Integer[0]);
    }


    public static GroupLiveStream[] getGroupLiveStreams()
    {
        var size = GroupLiveStreamManager.groupIdLiveStreamManagerMap.size();
        var result = new GroupLiveStream[size];
        var index = 0;
        for (var manager : GroupLiveStreamManager.groupIdLiveStreamManagerMap.values())
        {
            result[index] = manager.toGroupLiveStream();
            index++;
        }
        return result;
    }


    public static GroupLiveStreamManager addLiveStreamManager(int groupId, String name)
    {
        var ls = new GroupLiveStreamManager(groupId, name);
        ls.qw_group.clear();
        ls.qw_group.eq(ChatGroup.Column.ID.getName(), groupId);
        var g = new ChatGroup().selectOne(ls.qw_group);
        if (g == null)
            return null;
        GroupLiveStreamManager.groupIdLiveStreamManagerMap.put(ls.groupId, ls);
        return ls;
    }
    public static void removeLiveStreamManager(int groupId) {
        GroupLiveStreamManager.getLiveStreamManagerByGroupID(groupId).removeUserIds();
        GroupLiveStreamManager.groupIdLiveStreamManagerMap.remove(groupId);
    }
    public static GroupLiveStreamManager getLiveStreamManagerByGroupID(int groupId) {
        return GroupLiveStreamManager.groupIdLiveStreamManagerMap.get(groupId);
    }
    public static GroupLiveStreamManager getLiveStreamManagerByUserID(int userId) {
        return GroupLiveStreamManager.userIdLiveStreamManagerMap.get(userId);
    }
}


